var util = {};
const compileConfig = require("./apiurl")
const moment = require("./moment")
const JSEncrypt = require("./JSEncrypt").JSEncrypt
const publicKey =
	"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCR9TmiD16/VzQAuV0wUDw02LriHr4aVrnFRiepdMf8ocDVi4nz2UBbBugg44bRUpOj8Y9nx60LmDn9+RLCupmkfuyfJGPUyZB7pX36KTWWljtLysEJYSMzW/igavEpvAttGMDKZDfMPhfiUNJiFEtKK7QUQS3L2w3Hgpg1xzlWHwIDAQAB"
const encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);

var requestManager = new Map(); // 请求失败列表

var requestFailList = new Array();

var isDebugStatus = false;

/**
 * 执行http请求
 * @params url: 请求地址
 * @params data: 请求参数
 * @params options: 请求配置信息
 */

util.apphttp = (url, data = {}, options = {}) => {
	var method = options.method ? options.method : 'post'
	options = {
		method: method,
		loading: options.loading == false ? false : true,
		navigatorLoading: options.navigatorLoading ? options.navigatorLoading : false,
		loadingText: options.loadingText ? options.loadingText : '加载中...',
		contentType: options.contentType ? options.contentType : 'application/json',
		failshowToast: options.failshowToast == false ? false : true,
		networkCheck: options.networkCheck === false ? false : true, // 是否网络检测

		/** 
		 * 是否为必要请求
		 * @discuss：1、necessary 请求表示如果该次请求失败，则弹出提示框，
		 *             阻止界面上的下一步操作，来保证业务流程的正确性
		 *           2、常用语页面初始化失败的处理
		 *           3、默认get为necessary请求，如在options中指定了necessary, 则以该options.necessary为准
		 * */
		necessary: options.necessary == undefined ? false : options.necessary,

		/**
		 * 不要求权限验证
		 */
		tokenIgnore: options.tokenIgnore == undefined ? false : options.tokenIgnore
	};

	return new Promise(function(_success, _fail) {
		// 生成请求唯一表示 uuid
		var uuid = generateUUID();
		requestManager.set(uuid, {
			url,
			data,
			options,
			_success,
			_fail
		}); // 执行网络请求

		doRequest(uuid);
	});
};
/**
 * 执行网络请求
 */


function doRequest(uuid) {

	// 获取请求信息
	var {
		url,
		data,
		options,
		_success,
		_fail
	} = requestManager.get(uuid);

	if (options.loading || options.navigatorLoading) {
		if (options.loading && !options.navigatorLoading) {
			console.log("options.loading: " + url)
		}

		showRequestLoading(options.loadingText, options.navigatorLoading);
	}

	if (!options.tokenIgnore && !uni.getStorageSync('token')) {
		showLoginError();

		if (_fail) {
			_fail("loginError");
		}

		return;
	}

	var code_fill_str = ["000000", "00000", "0000", "000", "00", "0"]
	var code = "" + parseInt(Math.random() * 1000000)
	var randomStr = (code.length >= 6 ? '' : code_fill_str[code.length]) + code
	var requestKeyValue = "zhongguohong" + moment().format("yyyyMMDDHHmmss") + randomStr
	let encrypted = encrypt.encrypt(requestKeyValue);

	uni.request({
		url: url,
		data: data,
		method: options.method,
		header: {
			'Content-type': options.contentType,
			'qianl': 'qianl',
			'Authorization': 'Bearer ' + uni.getStorageSync('token'),
			'Yx2-Language': compileConfig.language === "en-common" ? 'en-US' : 'zh-CN',
			"Iz1QRGdVYXQqXmJ4": encrypted
		},
		success: function(res) {
			// 服务端正常返回
			console.log(res.data, '\nurl:' + url + '\ndata:', data); // 未登录处理

			if (res.data.code == 389 && res.data.msg == '认证失败' || res.code == 389 && res
				.msg == '认证失败' || res.data.code == 389 && res.data.msg == '认证失败，请重新登陆。' || res.data.msg ==
				'您长时间未登陆，请重新登陆。' || res.data.msg == '您长时间未登录，请重新登录。'
			) {
				// 从请求的集合中删除
				requestManager.delete(uuid); // 弹出登录界面

				showLoginError();
				return;
			}

			if (res.data.status >= 200 && res.data.status <= 300 || res.data.code <=
				300 && res.data.code >= 200 || res.data.status === 0 && res.data
				.message == '操作成功') {
				// 请求成功的处理
				succeedResultHandle(res, _success, uuid);
			} else {

				failResultHandle(options, res, _fail, uuid);
			}
		},
		fail: function(err) {
			console.log(err, '\nfailurl=>:' + url + '\ndata:', data); // 请求失败处理

			failResultHandle(options, err, _fail, uuid);
		},
		complete: function() {
			if (requestFailList.length > 0) {
				console.log('-----------------------------------------------------');
				console.log('当前未完成请求列表：');
				console.log(requestManager);
				console.log('-----------------------------------------------------');
				console.log('当前请求失败列表：');
				console.log(requestFailList);
			}

			if (options.loading || options.navigatorLoading) {
				hideRequestLoading(options.navigatorLoading);
			}
		}
	});
}

var loading = false;
var navigatorLoading = false;

function showRequestLoading(loadingText, isNavigatorLoading) {
	if (isNavigatorLoading) {
		if (!navigatorLoading) {
			uni.showNavigationBarLoading({});
			navigatorLoading = true;
		}
	} else {
		if (!loading) {
			uni.showLoading({
				title: loadingText,
				mask: true
			});
			loading = true;
		}
	}
}

function hideRequestLoading(isNavigatorLoading) {
	var showLoadingCount = 0;

	for (var request of requestManager.values()) {
		if (isNavigatorLoading) {
			if (request.options && request.options.navigatorLoading) {
				showLoadingCount++;
			}
		} else {
			if (request.options && request.options.loading && !request.options.navigatorLoading) {
				showLoadingCount++;
			}
		}
	}

	if (showLoadingCount <= 0) {
		setTimeout(() => {
			var showLoadingCount1 = 0;

			for (var request of requestManager.values()) {
				if (isNavigatorLoading) {
					if (request.options && request.options.navigatorLoading) {
						showLoadingCount1++;
					}
				} else {
					if (request.options && request.options.loading && !request.options.navigatorLoading) {
						showLoadingCount1++;
					}
				}
			}

			if (showLoadingCount1 <= 0) {
				if (isNavigatorLoading) {
					uni.hideNavigationBarLoading({});
					navigatorLoading = false;
				} else {
					if (toastLock) {
						setTimeout(() => {
							uni.hideLoading({})
							loading = false
						}, 1500);
					} else {
						uni.hideLoading({})
						loading = false
					}
				}
			}
		}, 300);
	}
}
/**
 * 请求成功处理
 */


function succeedResultHandle(res, _success, uuid) {
	if (isFunction(_success)) {
		// 返回请求成功
		_success(res.data);
	} // 从请求的集合中删除


	requestManager.delete(uuid);
}
/**
 * 请求失败处理
 */


function failResultHandle(options, res, _fail, uuid) {
	if (options.necessary) {
		// 如果是必要请求
		// 加入到请求失败列表
		requestFailList.push([uuid, res]); // 显示系统错误

		showSytemError();
	} else if (getApp().globalData.isRequestErrorVisible != true) {
		// 非必要请求失败处理
		if (options.failshowToast) {
			// 是否要显示系统返回信息
			showErrorToast(res);
		} // 返回请求失败


		if (_fail != null && isFunction(_fail)) {
			_fail(res);
		} // 从请求的集合中删除


		requestManager.delete(uuid);
	}
}
var toastLock = false

function showErrorToast(res) {
	var title = ""
	if (res.data) {
		if (res.data.msg) {
			title = res.data.msg
		} else if (res.data.status) {
			title = '服务器' + res.data.status
		} else if (res.data.code) {
			title = '服务器' + res.data.code
		} else if (res.data.statusCode) {
			title = '服务器' + res.data.statusCode
		}
	} else if (res.errMsg) {
		title = '服务器' + res.errMsg
	}
	toastLock = true
	uni.showToast({
		icon: "none",
		title: title,
		complete: () => {
			toastLock: false
		}
	});
}

/**
 * 重新发送失败的请求
 */
function retryFailedRequest() {
	var failedList = requestFailList; // 清空之前的请求失败列表

	requestFailList = new Array();
	failedList.map(data => {
		var uuid = data[0];
		doRequest(uuid);
	});
}
/**
 * 稍后再试
 */


function giveUpFailedRequest() {
	var failedList = requestFailList; // 清空之前的请求失败列表

	requestFailList = new Array();
	failedList.map(data => {
		var uuid = data[0];
		var {
			_fail
		} = requestManager.get(uuid);
		requestManager.delete(uuid); // 返回错误

		if (_fail != null && isFunction(_fail)) {
			_fail({
				errMsg: ''
			});
		}

		uni.navigateBack({});
	});
}
/**
 * 网络状态描述
 */


function networkTypeDesc(networkType) {
	if (networkType == 'wifi') {
		return 'wifi 网络';
	} else if (networkType == '2g') {
		return '2g 网络';
	} else if (networkType == '3g') {
		return '3g 网络';
	} else if (networkType == '4g') {
		return '4g 网络';
	} else if (networkType == '5g') {
		return '5g 网络';
	} else if (networkType == 'none') {
		return '无网络';
	} else if (networkType == 'unknown') {
		return 'Android 下不常见的网络类型';
	}
}
/**
 * 显示登录界面
 */

function showLoginError() {
	// 未登录或者token值丢失
	console.log('-----------------------------------------------------');
	console.log('无权限，跳转登录界面');

	var yx2Mediator = require('../mediator/yx2-mediator-login.js')
	yx2Mediator.reLanuchToLogin()

	// uni.redirectTo({
	// 	url: '/packages/loginPack/index/index'
	// });
};
/**
 * 显示网络错误
 */


function showNetWorkError(networkType) {
	if (getApp().globalData.isRequestErrorVisible) return;
	getApp().globalData.isRequestErrorVisible = true;
	var titleString = isDebugStatus ? '网络不稳定【' + networkType + '】' : '网络不稳定';
	titleString = '网络不稳定【' + networkType + '】';
	uni.showModal({
		title: titleString,
		content: '当前网络不稳定，请检查网络或稍后再试',
		cancelText: '稍候再试',
		cancelColor: '#999999',
		confirmText: '重新加载',
		confirmColor: '#FF8F28',

		success(res) {
			if (res.confirm) {
				// 重新发送失败的请求
				retryFailedRequest();
			} else if (res.cancel) {
				// 稍后再试
				giveUpFailedRequest();
			}
		},

		complete() {
			getApp().globalData.isRequestErrorVisible = false;
		}

	});
}
/**
 * 显示网络错误
 */


function showSytemError() {
	if (getApp().globalData.isRequestErrorVisible) return;
	getApp().globalData.isRequestErrorVisible = true;
	var contentString = '当前系统异常，请稍候重新尝试';

	if (isDebugStatus) {
		// 开发模式下的显示处理
		contentString = '';
		requestFailList.map(data => {
			var uuid = data[0];
			var error = data[1].data == undefined ? data[1] : data[1].data;
			var {
				url
			} = requestManager.get(uuid);
			contentString += '请求地址：' + url;
			contentString += '------------------------错误信息：\n' + JSON.stringify(error) + '\n';
		});
	}

	uni.showModal({
		title: '系统异常',
		content: contentString,
		cancelText: '稍候再试',
		cancelColor: '#999999',
		confirmText: '重新加载',
		confirmColor: '#FF8F28',

		success(res) {
			if (res.confirm) {
				// 重新发送失败的请求
				retryFailedRequest();
			} else if (res.cancel) {
				// 稍后再试
				giveUpFailedRequest();
			}
		},

		complete() {
			getApp().globalData.isRequestErrorVisible = false;
		}

	});
}
/**
 * 生成请求的唯一标识
 */


function generateUUID() {
	var s = [];
	var hexDigits = "0123456789abcdef";

	for (var i = 0; i < 36; i++) {
		s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
	}

	s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010

	s[19] = hexDigits.substr(s[19] & 0x3 | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01

	s[8] = s[13] = s[18] = s[23] = "-";
	var uuid = s.join("");
	return uuid;
}

function isFunction(f) {
	return 'function' === typeof f;
} // 获取页面传值的方法


util.getPageInfo = function(res) {
	let pages = getCurrentPages(); //获取加载的页面

	let currentPage = pages[pages.length - 1]; //获取当前页面的对象

	let url = currentPage.route; //当前页面url

	let options = currentPage.options;
	return {
		'url': url,
		'options': options
	};
}; // 节流函数


util.throttle = function throttle(fn, gapTime) {
	if (gapTime == null || gapTime == undefined) {
		gapTime = 1500;
	}

	let _lastTime = null;
	return function() {
		let _nowTime = +new Date();

		if (_nowTime - _lastTime > gapTime || !_lastTime) {
			fn.apply(this, arguments);
			_lastTime = _nowTime;
		}
	};
};

module.exports = util;